package cn.openea.perpartner.meily.web.service.logistics;

import cn.openea.perpartner.common.core.exception.ServiceException;
import cn.openea.perpartner.meily.constant.enums.ExpressCompany;
import cn.openea.perpartner.meily.constant.enums.ExpressStatus;
import cn.openea.perpartner.meily.constant.enums.LogisticsModule;
import cn.openea.perpartner.meily.thirdparty.ExpressServiceApi;
import cn.openea.perpartner.meily.web.entity.LogisticsInfo;
import cn.openea.perpartner.meily.web.entity.dto.LogisticsDTOFactory.LogisticsRealTimeDTO;
import cn.openea.perpartner.meily.web.entity.vo.LogisticsSearchVo;
import cn.openea.perpartner.meily.web.mapper.LogisticsInfoMapper;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author ysk
 * @version 1.0.1
 * @Description 物流查询
 * @createTime 2023年05月10日 14:04:00
 */
@Slf4j
@Service
public class LogisticsQuery {

    @Resource
    private LogisticsInfoMapper logisticsInfoMapper;
    @Resource
    private ExpressServiceApi expressServiceApi;


    public LogisticsInfo findByModuleAndModuleId(@NonNull LogisticsModule logisticsModule, String moduleId) {
        if (StringUtils.isBlank(moduleId)) {
            throw new ServiceException("moduleId is blank");
        }
        LambdaQueryWrapper<LogisticsInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LogisticsInfo::getModule, logisticsModule.getModuleCode());
        queryWrapper.eq(LogisticsInfo::getModuleId, moduleId);
        return logisticsInfoMapper.selectOne(queryWrapper);
    }

    /**
     * 获取物流信息
     *
     * @param company       快递公司
     * @param courierNumber 快递单号
     * @param phone         手机号
     */
    public LogisticsInfo findByCompanyAndCourierNumberAndPhone(ExpressCompany company, String courierNumber, String phone) {
        if (StringUtils.isBlank(courierNumber) || StringUtils.isBlank(phone)) {
            throw new ServiceException("courierNumber or phone is blank");
        }
        LogisticsInfo logisticsInfo = logisticsInfoMapper.selectOne(buildQueryWrapper(LogisticsSearchVo
                .builder()
                .company(company)
                .courierNumber(courierNumber)
                .phone(phone)
                .build(), false));
        if (logisticsInfo == null) {
            // 这个时候数据库可能还没将数据保存，查实时物流
            LogisticsRealTimeDTO realTimeDTO = expressServiceApi.realTimeLogistics(company, courierNumber, phone);
            if (company == null) {
                company = ExpressCompany.getByCode(realTimeDTO.getCom());
            }
            logisticsInfo = new LogisticsInfo();
            logisticsInfo.setStatus(realTimeDTO.getState());
            logisticsInfo.setExpressCompany(company != null ? company.getCode() : "");
            logisticsInfo.setCourierNumber(courierNumber);
            logisticsInfo.setPhone(phone);
            logisticsInfo.setDynamicContext(JSONObject.toJSONString(realTimeDTO.getLogisticsDynamicList()));
        }
        return logisticsInfo;
    }


    /**
     * 获取物流信息
     *
     * @param searchVo 对应模块的数据ID
     */
    public List<LogisticsInfo> findBySearchVo(LogisticsSearchVo searchVo) {
        return logisticsInfoMapper.selectList(buildQueryWrapper(searchVo, true));
    }

    private LambdaQueryWrapper<LogisticsInfo> buildQueryWrapper(LogisticsSearchVo searchVo, boolean isSort) {
        if (searchVo == null) {
            return null;
        }
        LambdaQueryWrapper<LogisticsInfo> queryWrapper = new LambdaQueryWrapper<>();
        ExpressCompany company = searchVo.getCompany();
        if (company != null) {
            queryWrapper.eq(LogisticsInfo::getExpressCompany, company.getCode());
        }
        LogisticsModule logisticsModule = searchVo.getLogisticsModule();
        if (logisticsModule != null) {
            queryWrapper.eq(LogisticsInfo::getModule, logisticsModule.getModuleCode());
        }
        if (searchVo.getExistLogistics() != null && searchVo.getExistLogistics()) {
            // 排除掉没有物流信息的记录 历史记录已经完成的业务默认都是签收的
            queryWrapper.ne(LogisticsInfo::getStatus, ExpressStatus.NO_LOGISTICS.getStatus());
        }
        if (searchVo.getInTransit() != null && searchVo.getInTransit()) {
            // 是否为运输中的物流 排除掉已签收物流
            queryWrapper.ne(LogisticsInfo::getStatus, ExpressStatus.SIGN.getStatus());
        }
        if (StringUtils.isNotBlank(searchVo.getUserId())) {
            queryWrapper.eq(LogisticsInfo::getUserId, searchVo.getUserId());
        }
        if (StringUtils.isNotBlank(searchVo.getCourierNumber())) {
            queryWrapper.eq(LogisticsInfo::getCourierNumber, searchVo.getCourierNumber());
        }
        if (StringUtils.isNotBlank(searchVo.getConsigneeName())) {
            queryWrapper.eq(LogisticsInfo::getConsigneeName, searchVo.getConsigneeName());
        }
        if (StringUtils.isNotBlank(searchVo.getTradingId())) {
            queryWrapper.eq(LogisticsInfo::getTradingId, searchVo.getTradingId());
        }
        if (StringUtils.isNotBlank(searchVo.getPhone())) {
            queryWrapper.eq(LogisticsInfo::getPhone, searchVo.getPhone());
        }
        if (searchVo.getStatus() != null) {
            queryWrapper.eq(LogisticsInfo::getStatus, searchVo.getStatus());
        }
        if (searchVo.getBusinessStatus() != null) {
            queryWrapper.eq(LogisticsInfo::getBusinessStatus, searchVo.getBusinessStatus());
        }
        if (isSort) {
            // 默认根据发货实际排序
            queryWrapper.orderByDesc(LogisticsInfo::getDeliveryTime);
        }
        return queryWrapper;
    }


    /**
     * 根据用户Id查询当前用户的所有快递记录
     *
     * @param userId
     * @return
     */
    public List<LogisticsInfo> findLogisticsByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return new ArrayList<>();
        }
        return logisticsInfoMapper.selectList(new LambdaQueryWrapper<LogisticsInfo>()
                .eq(LogisticsInfo::getUserId, userId));
    }

    /**
     * 查询运输中的数据
     */
    public List<LogisticsInfo> findInTransportLogisticsList() {
        return logisticsInfoMapper.selectList(new LambdaQueryWrapper<LogisticsInfo>()
                .ne(LogisticsInfo::getStatus, ExpressStatus.SIGN.getStatus()));
    }

    public Map<String, Integer> logisticsStatusStatistics(LogisticsSearchVo searchVo) {
        return logisticsInfoMapper.logisticsStatusStatistics(buildQueryWrapper(searchVo, false));
    }

    public List<LogisticsInfo> findFortyEightHourData(LogisticsSearchVo searchVo) {
        LambdaQueryWrapper<LogisticsInfo> queryWrapper = buildQueryWrapper(searchVo, false);
        queryWrapper.apply("delivery_time + INTERVAL 10  DAY > NOW() AND delivery_time + INTERVAL 10 DAY < DATE_ADD(NOW(), INTERVAL 48 HOUR)");
        return logisticsInfoMapper.selectList(queryWrapper);
    }

    public List<LogisticsInfo> findInLogisticsListBycBusinessStatus(short status) {
        return logisticsInfoMapper.selectList(new LambdaQueryWrapper<LogisticsInfo>()
                .eq(LogisticsInfo::getBusinessStatus, status));
    }
}
